#!/usr/bin/python

from google.appengine.ext import db


class Institution(db.Expando):
  # First-level children: Doctors and Schedules

  name = db.StringProperty(required=True)


class Doctor(db.Expando):

  # Foreign key, parent relationship.
  institution = db.ReferenceProperty(Institution, required=True)

  # Properties for the doctor.
  login = db.UserProperty(required=True)
  name = db.StringProperty(required=True)

  # These are all default values.
  min_shifts = db.IntegerProperty(required=True, default=15)
  max_shifts = db.IntegerProperty(required=True, default=15)
  max_night_shifts = db.IntegerProperty(required=True, default=5)
  max_consecutive_days = db.IntegerProperty(required=True, default=5)
  # TODO Support active property
  active = db.BooleanProperty(default=True)


class Schedule(db.Model):
  # First-level children: ScheduleBlocks, DoctorConstraints, ScheduleSolutions

  # Foreign key, parent relationship.
  institution = db.ReferenceProperty(Institution, required=True)

  # Info for the schedule
  start_time = db.DateTimeProperty(required=True)


# TODO Merge min/max properties
# DoctorConstraint/SchedulingInstanceConstraint?
class DoctorConstraint(db.Model):

  # Foreign key, reference relationship.
  doctor = db.ReferenceProperty(Doctor, required=True)

  # Foreign key, parent relationship.
  schedule = db.ReferenceProperty(Schedule, required=True)

  # Some of these properties have defaults that are overridden for the instance
  days_off = db.ListProperty(long)
  min_shifts = db.IntegerProperty(required=True, default=15)
  max_shifts = db.IntegerProperty(required=True, default=15)
  max_night_shifts = db.IntegerProperty(required=True, default=5)
  max_consecutive_days = db.IntegerProperty(required=True, default=5)


class ScheduleBlock(db.Model):

  # Foreign key, parent relationship.
  schedule = db.ReferenceProperty(Schedule, required=True)

  # Time and duration.
  start_time = db.DateTimeProperty(required=True)
  duration_minutes = db.IntegerProperty(required=True, default=12*60)


class ScheduleSolution(db.Expando):
  # First-level children: ScheduleSolutionBlock

  # Foreign key, parent relationship.
  schedule = db.ReferenceProperty(Schedule, required=True)

  # Messages that accompany the solution.
  message = db.TextProperty()


class ScheduleSolutionBlock(db.Model):

  # Foreign key, parent relationship.
  solution = db.ReferenceProperty(ScheduleSolution, required=True)

  # Foreign key, reference relationship.
  block = db.ReferenceProperty(ScheduleBlock, required=True)

  # Foreign key, reference relationship.
  doctor = db.ReferenceProperty(Doctor, required=True)
